#ifndef _SOCK_ADDR_HPP_20120407
#define _SOCK_ADDR_HPP_20120407

#include "base.hpp"

namespace tcp
{
	class SockAddr
	{
		public :
			SockAddr()
				: _addr(0), _port(0)
			{
			}

			SockAddr(int port)
			{
				_addr    = INADDR_ANY;
				_port    = port;
			}

			SockAddr(int addr, int port)
			{
				_addr   = ((0 == addr)? INADDR_ANY: addr);
				_port   = port;
			}
			
			SockAddr(const char * hostname, int port)
			{
				if (NULL == hostname)
				{
					_addr  = INADDR_ANY;
				}
				else
				{
					_addr  = ::ntohl(::inet_addr(hostname));
				}
				
				_port      = port;
			}

			SockAddr(const struct sockaddr_in & in4)
			{
				_addr    = ::ntohl(in4.sin_addr.s_addr);
				_port    = ::ntohs(in4.sin_port);
			}

			void reset(const char * hostname, int port)
			{
				new (this) SockAddr(hostname, port);
			}

			void reset(int addr, int port)
			{
				new (this) SockAddr(addr, port);
			}

			void reset(const struct sockaddr_in & ip4)
			{
				new (this) SockAddr(ip4);
			}

			int port() const { return _port; }
			int addr() const { return _addr; }

			bool to_sockaddr(struct sockaddr_in & ip4, int & len)
			{
				if (0 == _port)
				{
					return false;
				}

				::bzero(&ip4, sizeof(ip4));
				ip4.sin_port        = ::htons((short)_port);
				ip4.sin_addr.s_addr = ::htonl(_addr);
				ip4.sin_family      = AF_INET;

				len                 = sizeof(ip4);

				return true;
			}

			const char * dot_addr() const
			{
				in_addr addr;
				addr.s_addr = ::htonl(_addr);
				return ::inet_ntoa(addr);
			}

		public :
			int _addr;
			int _port;
	};
};

#endif

